<?php
/**
 * 地铁模型
 */

namespace app\admin\model;


use app\common\lib\RespCode;
use app\common\model\BaseModel;
use custom\Err;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;
use think\exception\PDOException;
use think\facade\Cache;

class Metro extends BaseModel {

    /**
     * 地铁列表
     * @param $params
     * @return array
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public static function getList($params) {
        $region_data = Db::name('region')
            ->where('city_code', $params['city_code'])
            ->find();
        $codes = $region_data['p_codes'] . $params['city_code'] . ',';
        $data = db('metro')
            ->where('city_codes', 'like', trim($codes) . '%')
            ->field('id,pid,name,id as mid')
            ->order('metro_sort', 'asc')
            ->select();
        $data = self::listToTree($data);
        foreach ($data as $k => $v) {
            unset($data[$k]['pid']);
            unset($data[$k]['lng']);
            unset($data[$k]['lat']);
            if (!empty($data[$k]['children'])) {
                foreach ($data[$k]['children'] as $k1 => $v1) {
                    unset($data[$k]['children'][$k1]['pid']);
                    unset($data[$k]['children'][$k1]['id']);
                }
            } else $data[$k]['children'] = [];
        }
        return array_values($data);
    }

    /**
     * 数组转树
     * @param $list
     * @param string $pk
     * @param string $pid
     * @param string $child
     * @param int $root
     * @return array
     */
    public static function listToTree($list, $pk = 'id', $pid = 'pid', $child = 'children', $root = 0) {
        $tree = array();
        if (is_array($list)) {
            $refer = array();
            foreach ($list as $key => $data) {
                $refer[$data[$pk]] = &$list[$key];
            }
            foreach ($list as $key => $data) {
                // 判断是否存在parent
                $parentId = $data[$pid];
                if ($root == $parentId) {
                    $tree[$data[$pk]] = &$list[$key];
                } else {
                    if (isset($refer[$parentId])) {
                        $parent = &$refer[$parentId];
                        $parent[$child][$data[$pk]] = &$list[$key];
                        $parent[$child] = array_values($parent[$child]);
                    }
                }
            }
        }
        return $tree;
    }

    /**
     * 编辑
     * @param $params
     * @return bool
     * @throws Exception
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws PDOException
     */
    public static function edit($params) {
        $data = db("metro")->where('id', $params['id'])->find();
        if (empty($data)) {
            Err::add('数据不存在', RespCode::DATA_ERR);
            return false;
        }
        $pid = db("metro")
            ->where('id', $params['id'])
            ->value('pid');
        if (mb_strlen(trim($params['name']), 'utf-8') > 30) {
            Err::add('名称长度限制30', RespCode::DATA_ERR);
            return false;
        }
        //同一条线不能有相同站点
        $exists = db("metro")
            ->where('name', $params['name'])
            ->where('pid', $pid)
            ->select();
        if ($data['name'] != $params['name']) {
            if ($exists) {
                Err::add('该地铁站名已存在');
                return false;
            }
        }
        $update = [
            'name'     => $params['name'],
            'location' => Db::raw("POINT('{$params['lng']}', '{$params['lat']}')"),
            'lat'      => $params['lat'],
            'lng'      => $params['lng'],
        ];
        self::where('id', $params['id'])->update($update);
        return true;
    }

    /**
     * 编辑获取名称
     * @param $params
     * @return mixed
     */
    public static function getThisName($params, &$re) {
        $data = self::where('id', $params['id'])
            ->field('lng,lat,name,city_codes')
            ->find();
        $city_codes = explode(',', $data['city_codes']);
        $city_code = $city_codes[2];//返回市code
        if (empty($data)) {
            Err::add('数据不存在', RespCode::DATA_ERR);
            return false;
        }
        $re['name'] = $data['name'];
        $re['lat'] = $data['lat'];
        $re['lng'] = $data['lng'];
        $re['city_code'] = $city_code;
        return true;
    }

    /**
     * 新增线路
     * @param $params
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function addLinePost($params) {
        $name = trim($params['name']);
        if (mb_strlen($name, 'utf-8') > 30) {
            Err::add('线路名称长度限制30', RespCode::PARAMS_ERR);
            return false;
        }
        $region = Region::where('city_code', $params['city_code'])
            ->field("concat(p_codes,city_code, ',') as city_codes,name")
            ->findOrEmpty();
        if (empty($region)) {
            Err::add('请稍后尝试', RespCode::PARAMS_ERR);
            return false;
        }
        if (!self::where('city_codes', $region['city_codes'])
            ->where('name', $name)
            ->where('rank', 1)
            ->select()
            ->isEmpty()) {
            Err::add('线路名称已存在', RespCode::PARAMS_ERR);
            return false;
        }
        $data = [
            'city_codes' => $region['city_codes'],
            'city'       => $region['name'],
            'pid'        => 0,
            'name'       => $name,
            'rank'       => 1,
            'itime'      => time(),
            'lat'        => 0,
            'lng'        => 0,
            'location'   => Db::raw("POINT(0, 0)"),
            'metro_sort' => 0,
        ];
        if (!self::insert($data)) {
            Err::add('添加失败', RespCode::PARAMS_ERR);
            return false;
        }
        return true;
    }

    /**
     * 新增站点提交
     * @param $params
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function addSitePost($params) {
        $name = trim($params['name']);
        if (mb_strlen($name, 'utf-8') > 30) {
            Err::add('站点名称长度限制30', RespCode::PARAMS_ERR);
            return false;
        }
        $region = Region::where('city_code', $params['city_code'])
            ->field("concat(p_codes,city_code, ',') as city_codes,name")
            ->findOrEmpty();
        if (empty($region)) {
            Err::add('请稍后尝试', RespCode::PARAMS_ERR);
            return false;
        }

        if (!self::where('name', $name)
            ->where('rank', 2)
            ->where('pid', $params['line_id'])
            ->select()
            ->isEmpty()) {
            Err::add('同一线路不能出现相同站点名称', RespCode::PARAMS_ERR);
            return false;
        }
        //终点的下一站
        if ($params['type'] == 2) {
            $last_sort = self::where('pid', $params['line_id'])
                ->order('metro_sort desc')
                ->value('metro_sort');
            $metro_sort = $last_sort === null ? 0 : $last_sort + 1;
        }//起点的上一站
        else {
            $metro_sort = 0;
            $res1 = self::where('pid', $params['line_id'])
                ->order('metro_sort asc')
                ->column('id');
            if (!empty($res1)) {
                for ($i = 0; $i < count($res1); $i++) {
                    self::where('id', $res1[$i])
                        ->update(['metro_sort' => $i + 1]);
                }
            }
        }
        $data = [
            'city_codes' => $region['city_codes'],
            'city'       => $region['name'],
            'pid'        => $params['line_id'],
            'name'       => $name,
            'rank'       => 2,
            'itime'      => time(),
            'lat'        => $params['lat'],
            'lng'        => $params['lng'],
            'location'   => Db::raw("POINT({$params['lat']}, {$params['lng']})"),
            'metro_sort' => $metro_sort,
        ];
        if (!self::insert($data)) {
            Err::add('添加失败', RespCode::PARAMS_ERR);
            return false;
        }
        return true;
    }

    /**
     * 修改站点排序
     * @param $params
     * @throws \Exception
     */
    public static function editSort($params) {
        $ids = explode(',', $params['site_ids']);
        if ($ids) {
            $count = count($ids);
            for ($i = 0; $i < $count; $i++) {
                $arr = [
                    'id'         => $ids[$i],
                    'metro_sort' => $i
                ];
                $list[] = $arr;
            }
            $region = new self();
            $region->saveAll($list);
        }
    }
}
